package com.zunipe.trainticketsystem;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;

import com.zunipe.trainticketsystem.database.Result;
import com.zunipe.trainticketsystem.database.entity.Order;
import com.zunipe.trainticketsystem.database.entity.Train;
import com.zunipe.trainticketsystem.database.entity.User;
import com.zunipe.trainticketsystem.database.handler.OrderHandler;
import com.zunipe.trainticketsystem.database.handler.TrainHandler;
import com.zunipe.trainticketsystem.database.handler.UserHandler;
import com.zunipe.trainticketsystem.databinding.ActivityTrainInfoBinding;
import com.zunipe.trainticketsystem.util.RandomUtil;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TrainInfoActivity extends AppCompatActivity implements View.OnClickListener {
    ActivityTrainInfoBinding binding;
    private int selectId;
    private TrainHandler trainHandler;
    private List<Train> trainList;
    private List<Integer> effectiveButtonList;
    private String trainNumber;
    private UserHandler userHandler;
    private OrderHandler orderHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityTrainInfoBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        setSupportActionBar(binding.toolbar);
        if (getSupportActionBar() != null)
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        selectId = -1;
        effectiveButtonList = new ArrayList<>();

        trainHandler = new TrainHandler();
        userHandler = new UserHandler();
        orderHandler = new OrderHandler();

        Intent intent = getIntent();
        trainNumber = intent.getStringExtra("trainNumber");
        if (trainNumber == null) {
            exitDueInvalidParameters();
        }

        updateUI();
        // 点击购票按钮
        binding.btnSubmitOrder.setOnClickListener(v -> {
            String type = "";
            switch (selectId) {
                case 0:
                    type = "二等";
                    break;
                case 1:
                    type = "一等";
                    break;
                case 2:
                    type = "特等";
                    break;
                case 3:
                    type = "无座";
                    break;
            }
            if (type.isEmpty()) {
                Toast.makeText(this, "请选择等级", Toast.LENGTH_SHORT).show();
                return;
            }
            // 进行模拟抢票
            simulateTicketGrabbing(type);
        });
    }

    private void simulateTicketGrabbing(String trainType) {
        ProgressDialog dialog = ProgressDialog.show(this, "提示", "正在抢票中,请稍后...", false, true);
        Train targetTrain = trainHandler.getByTrainNumberAndType(trainNumber, trainType);
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(6);
        Random r = new Random();
        Map<Integer, User> simulateUserMap = new HashMap<>();
        int simulateUserIndex = 1;
        int yourNumber = r.nextInt(6); // 模拟抢票时候前后时间差异
        // 把自己添加进去
        simulateUserMap.put(yourNumber, userHandler.getUserById(6));
        Log.d("TEST", "UserID: " + yourNumber);
        for (int i = 0; i < 6; ++i) {
            final int finalI = i;
            if (i != yourNumber) {
                // 赋予模拟用户身份
                User user = userHandler.getUserById(simulateUserIndex);
                simulateUserMap.put(i, user);
                simulateUserIndex++;
            }
            fixedThreadPool.execute(() -> {
                try {
                    Thread.sleep(2000);
                    Result result = trainHandler.buyTicket(targetTrain);
                    new Handler(Looper.getMainLooper()).post(() -> {
                        if (result.getCode() == Result.SUCCESS_CODE) { // 抢票成功
                            if (finalI == yourNumber) { // 如果是你抢到了票
                                NotificationManager notificationManager = getSystemService(NotificationManager.class);
                                NotificationChannel channel = new NotificationChannel(TrainTicketApplication.CHANNEL_ID, "Train", NotificationManager.IMPORTANCE_HIGH);
                                notificationManager.createNotificationChannel(channel);
                                Notification notification = new Notification.Builder(this, TrainTicketApplication.CHANNEL_ID)
                                        .setContentText("抢票系统")
                                        .setContentText("恭喜你抢到票了")
                                        .setSmallIcon(R.drawable.ic_launcher_foreground)
                                        .build();
                                notificationManager.notify(1, notification);
                                // 跳转到订单确认页面
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
                                Order order = new Order()
                                        .setTrainId(targetTrain.getId())
                                        .setUserId(simulateUserMap.get(finalI).getId())
                                        .setOrderNumber(RandomUtil.generateOrderNumber())
                                        .setTime(sdf.format(System.currentTimeMillis()))
                                        .setStatus("未付款")
                                        .setPrice(targetTrain.getPrice());
                                int id = orderHandler.createOrder(order);
                                Intent intent = new Intent(this, OrderPaymentActivity.class);
                                intent.putExtra("id", id);
                                startActivity(intent);
                            } else {
                                // 如果是模拟用户，直接向数据库中添加订单记录
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
                                Order order = new Order()
                                        .setTrainId(targetTrain.getId())
                                        .setUserId(simulateUserMap.get(finalI).getId())
                                        .setOrderNumber(RandomUtil.generateOrderNumber())
                                        .setTime(sdf.format(System.currentTimeMillis()))
                                        .setStatus("已付款")
                                        .setPrice(targetTrain.getPrice());
                                orderHandler.createOrder(order);
                            }
                            updateUI(); // 刷新UI
                        } else if (finalI == yourNumber) {
                            Toast.makeText(this, "非常可惜，没有抢到票", Toast.LENGTH_SHORT).show();
                        }
                        dialog.cancel();
                    });
                } catch (InterruptedException ignored) {

                }
            });
        }
    }

    private void initUI() {
        effectiveButtonList.clear();

        binding.tvSecondPrice.setText(getString(R.string.price, 0.0));
        binding.tvSecondCount.setText(getString(R.string.count, 0));
        binding.tvSecondName.setTextColor(getColor(R.color.invalid));
        binding.btnSecond.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_invalid_bg));
        binding.btnSecond.setOnClickListener(null);

        binding.tvFirstPrice.setText(getString(R.string.price, 0.0));
        binding.tvFirstCount.setText(getString(R.string.count, 0));
        binding.tvFirstName.setTextColor(getColor(R.color.invalid));
        binding.btnFirst.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_invalid_bg));
        binding.btnFirst.setOnClickListener(null);

        binding.tvSpecialPrice.setText(getString(R.string.price, 0.0));
        binding.tvSpecialCount.setText(getString(R.string.count, 0));
        binding.tvSpecialName.setTextColor(getColor(R.color.invalid));
        binding.btnSpecial.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_invalid_bg));
        binding.btnSpecial.setOnClickListener(null);

        binding.tvNonePrice.setText(getString(R.string.price, 0.0));
        binding.tvNoneCount.setText(getString(R.string.count, 0));
        binding.tvNoneName.setTextColor(getColor(R.color.invalid));
        binding.btnNone.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_invalid_bg));
        binding.btnNone.setOnClickListener(null);
    }

    private void updateUI() {
        // 通知主界面更新UI
        Intent updateHomePageListBroadcast = new Intent();
        updateHomePageListBroadcast.setAction("com.zunipe.trainticketsystem.update.home.list");
        updateHomePageListBroadcast.setPackage("com.zunipe.trainticketsystem");
        sendBroadcast(updateHomePageListBroadcast);

        Intent updateOrderPageListBroadcast = new Intent();
        updateOrderPageListBroadcast.setAction("com.zunipe.trainticketsystem.update.order.list");
        updateOrderPageListBroadcast.setPackage("com.zunipe.trainticketsystem");
        sendBroadcast(updateOrderPageListBroadcast);

        trainList = trainHandler.getTrainListByTrainNumber(trainNumber); // 从数据库获取该车次号的所有座位信息
        if (trainList.isEmpty()) {
            exitDueInvalidParameters();
        }

        initUI();
        for (int i = 0; i < trainList.size(); ++i) {
            Train train = trainList.get(i);
            if (i == trainList.size() - 1) {
                binding.tvPlaceOfStart.setText(train.getPlaceOfStart());
                binding.tvPlaceOfEnd.setText(train.getPlaceOfEnd());
                binding.tvStartTime.setText(train.getStartTime());
                binding.tvEndTime.setText(train.getEndTime());
                binding.tvTrainNumber.setText(trainNumber);
            }
            setSelectButtonByType(train);
        }
    }

    private void setSelectButtonByType(Train train) {
        if (train.getCount() > 0) {
            switch (train.getType()) {
                case "二等":
                    binding.tvSecondPrice.setText(getString(R.string.price, train.getPrice()));
                    binding.tvSecondCount.setText(getString(R.string.count, train.getCount()));
                    binding.tvSecondName.setTextColor(getColor(R.color.black));
                    binding.btnSecond.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_bg));
                    effectiveButtonList.add(R.id.btn_second);
                    binding.btnSecond.setOnClickListener(this);
                    break;
                case "一等":
                    binding.tvFirstPrice.setText(getString(R.string.price, train.getPrice()));
                    binding.tvFirstCount.setText(getString(R.string.count, train.getCount()));
                    binding.tvFirstName.setTextColor(getColor(R.color.black));
                    binding.btnFirst.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_bg));
                    effectiveButtonList.add(R.id.btn_first);
                    binding.btnFirst.setOnClickListener(this);
                    break;
                case "特等":
                    binding.tvSpecialPrice.setText(getString(R.string.price, train.getPrice()));
                    binding.tvSpecialCount.setText(getString(R.string.count, train.getCount()));
                    binding.tvSpecialName.setTextColor(getColor(R.color.black));
                    binding.btnSpecial.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_bg));
                    effectiveButtonList.add(R.id.btn_special);
                    binding.btnSpecial.setOnClickListener(this);
                    break;
                case "无座":
                    binding.tvNonePrice.setText(getString(R.string.price, train.getPrice()));
                    binding.tvNoneCount.setText(getString(R.string.count, train.getCount()));
                    binding.tvNoneName.setTextColor(getColor(R.color.black));
                    binding.btnNone.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_bg));
                    effectiveButtonList.add(R.id.btn_none);
                    binding.btnNone.setOnClickListener(this);
                    break;
            }
        }
    }

    private void exitDueInvalidParameters() {
        Toast.makeText(this, "无效的车次号", Toast.LENGTH_SHORT).show();
        finish();
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == android.R.id.home)
            finish();
        return true;
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_second) {
            selectId = 0;
        } else if (id == R.id.btn_first) {
            selectId = 1;
        } else if (id == R.id.btn_special) {
            selectId = 2;
        } else if (id == R.id.btn_none) {
            selectId = 3;
        }
        effectiveButtonList.forEach(c -> findViewById(c).setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_bg)));
        v.setBackground(AppCompatResources.getDrawable(this, R.drawable.train_type_button_select_bg));
    }
}